(495) 925-0049, ITShop интернет-магазин 229-0436, Учебный Центр 925-0049
  Главная страница Карта сайта Контакты
Поиск
Вход
Регистрация
Рассылки сайта
 
 
 
 
 

XML-сериализация для деплоймента начальных данных в Caché. Часть I

Источник: habrahabr
intersystems

 image
Думаю, не преувеличением будет сказать, что почти каждый разработчик информационной системы сталкивается с задачей формирования начальных данных при внедрении. 
У Caché-разработчиков есть несколько стандартных подходов к инициализации начальных данных: 

  • загрузка данных для классов-справочников из внешних файлов,
  • получение данных из онлайн-сервисов,
  • импорт статических данных из файлов-глобалов,
  • выполнение методов класса, создающих начальные данные из "зашитых" в код данных.

Для инициализации статических данных, небольших справочников или каких-либо конфигурационных данных системы, есть еще один способ, о котором пойдет речь в статье.

В Caché есть возможность включать в код класса блоки XML данных - XDATA блоки. Обычно эти данные используются для хранения вместе с классом данных о формах Zen-страниц и Zen-отчетов. В этих блоках можно также прекрасно хранить начальные данные для персистентных классов. 

Десериализация из XData

Рассмотрим пример простого хранимого класса с одним свойством. Это будет класс регионов с названиями - типичный пример справочника.

Код этого класса в Caché выглядит следующим образом:

Class map.Region Extends %Persistent
{
/// Название
Property 
Name As %String;
}


Добавим в класс начальные данные в XML-виде в блок XData:

XData populate
{
<
xml>
  <
item>
    <
Name>Красноярский край</Name>
  </
item>
  <
item>
    <
Name>Свердловская область</Name>
  </
item>
  <
item>
    <
Name>Хабаровский край</Name>
  </
item>
</
xml>
}


Для того, чтобы загрузить эти данные из класса, добавляем метод класса Populate. Кроме того, для работы с XML-данными необходимо класс сделать XML-enabled - добавляем в список наследования также класс %XML.Adaptor. В итоге преобразованный код класса выглядит следующим образом:

Class map.Region Extends (%Persistent%XML.Adaptor)
{

/// Название
Property 
Name As %String;

ClassMethod Populate() As %Status
{
  
#dim sc As %Status $$$OK
  
// очистка существующих данных класса
  
sc=..%DeleteExtent()  
  
if $$$ISERR(sc) quit sc
  
  
// загрузка xml-данных блока XData из библиотеки скомпилированных классов  
  
#dim stream As %Stream.Object ##class(%Dictionary.CompiledXData).%OpenId(..%ClassName(1) _ "//" "populate").Data
  
// создание инстанса XML ридера
  
#dim reader As %XML.Reader ##class(%XML.Reader).%New()
  
// открытие в ридере поток xml 
  
set sc = reader.OpenStream(stream, "literal")
  
if $$$ISERR(sc) quit sc
  
// указание ридеру в каком элементе искать данные класса
  
do reader.Correlate("item", ..%ClassName(1))
  
  
#dim obj as %Persistent
  
// загрука в цикле элементов класса
  
while reader.Next(.obj, .sc)
  
{
    
if $$$ISERR(sc) quit
    
// сохранение прочитанного из xml инстанс в базу данных
    
set sc = obj.%Save()
    
if $$$ISERR(sc) quit
    
    set 
obj = ""
  
}
  
  
quit sc
}

XData populate
{
<
xml>
  <
item>
    <
Name>Красноярский край</Name>
  </
item>
  <
item>
    <
Name>Свердловская область</Name>
  </
item>
  <
item>
    <
Name>Хабаровский край</Name>
  </
item>
</
xml>
}

}


Как видно из кода, всю работу выполняет класс %XML.Reader, который позволяет вычитывать "объектные" данные из XML.

Для загрузки данных в класс при деплойменте достаточно выполнить метод класса Populate:
##class(map.Region).Populate()

Убедимся, что инстансы класса действительно созданы. Выполним запрос в SQL-шелле терминала:

XMLDEPLOY>d $System.SQL.Shell()
SQL Command Line Shell
----------------------------------------------------
 
The command prefix is currently set to: <<nothing>>.
Enter q to quit, ? for help.
XMLDEPLOY>>select * from map.Region
1.      select * from map.Region
 
ID      Name
1       Красноярский край
2       Свердловская область
3       Хабаровский край
 
3 Rows(s) Affected
statement prepare time: 0.9125s, elapsed execute time: 0.0687s.
---------------------------------------------------------------------------
XMLDEPLOY>>quit
 
XMLDEPLOY>


Заполнение XData

Очевидно, что блок XData можно заполнить "вручную". И это удобно, если объектов в классе мало. Но если их много, это может сделать программа.
Воспользуемся классом %XML.Writer, который позволяет сериализовать в XML инстансы класса. 
Для этого добавляем в класс метод сериализации:

ClassMethod SerializeToFile(file as %Stringas %Status
{
  
#dim sc as %Status
  
#dim wr as %XML.Writer
  
set wr=##class(%XML.Writer).%New()
  
// установка файла, как устройство вывода
  
set sc=wr.OutputToFile(file) if $$$ISERR(sc) quit sc
  
// открытие корневого тега
  
set sc=wr.RootElement("xml"if $$$ISERR(sc) quit sc
  
#dim rset as %ResultSet
  
// выполнение запроса Extent, содержащего все объекты класса
  
set rset = ##class(%ResultSet).%New("map.Region:Extent")
   
do rset.Execute()
  
#dim obj
   
while (rset.Next()) {
     
set obj=##class(map.Region).%OpenId(rset.Data("ID"))
     
// сериализация объекта
     
set sc=wr.Object(obj)
     
if $$$ISERR(sc) quit
  
}
  
if $$$ISERR(sc) quit sc
  
// закрытие корневого тега
  
set sc=wr.EndRootElement() 
  
quit sc
}


Метод выводит в файл все объекты класса, сериализованные в XML.
Выполним метод в терминале:
XMLDEPLOY>D $System.OBJ.DisplayError(##class(map.Region).SerializeToFile("C:\cache\region.xml"))

XMLDEPLOY>

А затем откроем файл любым редактором/вьювером:
image
Полученный XML уже нетрудно вставить в блок XData. 

Итого

Аналогичным образом можно снабдить подобными методами все классы, требующие ввод начальных данных при деплойменте. В итоге, с помощью приведенной техники начальные данные хранятся вместе с классом, для которого они нужны, в технологичном XML-формате. Клиенту можно поставлять только код классов, а генерацию начальных данных выполнять с помощью метода Populate. А что делать, если классы связаны друг с другом? Этот и другие сценарии рассмотрим во второй части статьи. Продолжение следует…

Ссылки по теме


 Распечатать »
 Правила публикации »
  Написать редактору 
 Рекомендовать » Дата публикации: 24.07.2012 
 

Магазин программного обеспечения   WWW.ITSHOP.RU
IBM DOMINO COLLABORATION EXPRESS AUTHORIZED USER ANNUAL SW SUBSCRIPTION & SUPPORT RENEWAL
NauDoc Enterprise 10 рабочих мест
Quest Software. Toad for Oracle Development Suite
JIRA Software Commercial (Cloud) Standard 10 Users
VMware Fusion 10 Pro, ESD
 
Другие предложения...
 
Курсы обучения   WWW.ITSHOP.RU
 
Другие предложения...
 
Магазин сертификационных экзаменов   WWW.ITSHOP.RU
 
Другие предложения...
 
3D Принтеры | 3D Печать   WWW.ITSHOP.RU
 
Другие предложения...
 
Новости по теме
 
Рассылки Subscribe.ru
Информационные технологии: CASE, RAD, ERP, OLAP
Новости ITShop.ru - ПО, книги, документация, курсы обучения
Программирование на Microsoft Access
CASE-технологии
СУБД Oracle "с нуля"
Работа в Windows и новости компании Microsoft
Adobe Photoshop: алхимия дизайна
 
Статьи по теме
 
Новинки каталога Download
 
Исходники
 
Документация
 
 



    
rambler's top100 Rambler's Top100